#include "eventbus.h"
#include "string.h"

#define TOTAL_MEMORY_USAGE (MAX_EVENTS * 8 + MAX_CALLBACKS * 12 + EVENT_QUEUE_SIZE * 8 + 12)

/**
 * @brief 回调节点（一个事件可以有多个回调）
 */
typedef struct CallbackNode {
    EventCallback_TypeDef pfnCallback; // 回调函数
    void* pvFixedArgs;                 // 回调函数的固定参数（在注册时指定）
    struct CallbackNode* pstNext;      // 指向下一个回调节点
} CallbackNode_TypeDef;

/**
 * @brief 事件节点（一个事件ID对应一个事件节点）
 */
typedef struct EventNode {
    uint32_t u32EventID; // 事件ID
    CallbackNode_TypeDef* pstCallbackList; // 指向回调链表
} EventNode_TypeDef;

/**
 * @brief 事件队列成员（固定大小）
 */
typedef struct {
    uint32_t u32EventID; // 事件ID
    void* pvDynamicArgs; // 事件参数（触发时传递）
} EventQueueItem_TypeDef;

// 事件节点池（固定大小，每个事件ID对应一个事件节点）
static EventNode_TypeDef g_stEventNodes[MAX_EVENTS];

// 事件节点计数器
static uint32_t g_u32EventNodeCnt = 0;

// 回调节点池（固定大小）
static CallbackNode_TypeDef g_stCallbackPool[MAX_CALLBACKS];

// 空闲回调节点链表（用于管理空闲节点）
static CallbackNode_TypeDef* g_pstFreeCallbackList = NULL;

// 事件队列（固定大小）
static EventQueueItem_TypeDef g_stEventQueue[EVENT_QUEUE_SIZE];

// 事件队列头指针
static uint16_t u16EventQueueHead = 0;

// 事件队列尾指针
static uint16_t u16EventQueueTail = 0;

EventBusState_TypeDef
EventBus_Init(void) {
    // 初始化事件节点数组（全部置0）
    memset(g_stEventNodes, 0, sizeof(g_stEventNodes));

    // 初始化回调节点池：将所有节点连接成空闲链表
    g_pstFreeCallbackList = &g_stCallbackPool[0];
    for (int i = 0; i < MAX_CALLBACKS - 1; i++) {
        g_stCallbackPool[i].pstNext = &g_stCallbackPool[i+1];
    }
    g_stCallbackPool[MAX_CALLBACKS-1].pstNext = NULL;

    // 初始化事件队列
    u16EventQueueHead = 0;
    u16EventQueueTail = 0;

    // 返回成功
    return EVENT_OK;
}

EventBusState_TypeDef
EventBus_Connect( EventObject_TypeDef * pstEvent,
                  EventCallback_TypeDef pfnCallback,
                  void* pvFixedArgs){
    // 参数检查
    if(pstEvent == NULL || pfnCallback == NULL || pstEvent->pvEvent == NULL) {
        return EVENT_ERROR;
    }

    // 获取事件节点
    EventNode_TypeDef* pstEventNode = (EventNode_TypeDef*)pstEvent->pvEvent;

    // 检查回调是否已存在
    CallbackNode_TypeDef* pstCurrent = pstEventNode->pstCallbackList;
    while(pstCurrent != NULL) {
        if(pstCurrent->pfnCallback == pfnCallback &&
           pstCurrent->pvFixedArgs == pvFixedArgs) {  // 比较固定参数
            return EVENT_OK;  // 已存在直接返回
        }
        pstCurrent = pstCurrent->pstNext;
    }

    // 获取空闲回调节点
    if(g_pstFreeCallbackList == NULL) {
        return EVENT_FULL;
    }
    CallbackNode_TypeDef* pstNewNode = g_pstFreeCallbackList;
    g_pstFreeCallbackList = g_pstFreeCallbackList->pstNext;

    // 设置回调节点
    pstNewNode->pfnCallback = pfnCallback;
    pstNewNode->pvFixedArgs = pvFixedArgs;  // 保存固定参数

    // 添加到回调链表头部
    pstNewNode->pstNext = pstEventNode->pstCallbackList;
    pstEventNode->pstCallbackList = pstNewNode;

    // 返回成功
    return EVENT_OK;
}

EventBusState_TypeDef
EventBus_Emit( EventObject_TypeDef *pstEvent,
               void* pvDynamicArgs){

    if(pstEvent == NULL || pstEvent->pvEvent == NULL) {
        return EVENT_ERROR;
    }

    // 检查队列是否已满
    uint16_t u16NextTail = (u16EventQueueTail + 1) % EVENT_QUEUE_SIZE;
    if(u16NextTail == u16EventQueueHead) {
        return EVENT_FULL;
    }

    // 获取事件节点
    EventNode_TypeDef* pstEventNode = (EventNode_TypeDef*)pstEvent->pvEvent;

    // 入队操作
    g_stEventQueue[u16EventQueueTail].u32EventID = pstEventNode->u32EventID; // 保存事件ID
    g_stEventQueue[u16EventQueueTail].pvDynamicArgs = pvDynamicArgs;  // 保存动态参数
    u16EventQueueTail = u16NextTail;  // 使用预计算位置

    // 返回成功
    return EVENT_OK;
}

EventBusState_TypeDef
EventBus_CreateEvent(EventObject_TypeDef *pstEvent){

    // 判断输入参数是否合法
    if(pstEvent == NULL){
        return EVENT_ERROR;
    }

    // 判断事件池是否已满
    if(g_u32EventNodeCnt >= MAX_EVENTS){
        return EVENT_FULL;
    }

    // 创建事件节点
    EventNode_TypeDef *pstNode = &g_stEventNodes[g_u32EventNodeCnt++];
    pstNode->u32EventID = g_u32EventNodeCnt;
    pstEvent->pvEvent = pstNode;

    // 返回成功
    return EVENT_OK;
}

EventBusState_TypeDef
EventBus_Run(void){

    while(u16EventQueueHead != u16EventQueueTail) {
        // 获取事件位置
        uint16_t u16CurrentHead = u16EventQueueHead;

        // 获取事件数据
        uint32_t u32EventID = g_stEventQueue[u16CurrentHead].u32EventID;
        void* pvDynamicArgs = g_stEventQueue[u16CurrentHead].pvDynamicArgs;

        // 清除队列位置数据
        g_stEventQueue[u16CurrentHead].u32EventID = 0;
        g_stEventQueue[u16CurrentHead].pvDynamicArgs = NULL;

        // 更新头指针
        u16EventQueueHead = (u16CurrentHead + 1) % EVENT_QUEUE_SIZE;

        // 获取事件节点
        if(u32EventID >= MAX_EVENTS) continue;
        EventNode_TypeDef* pstEventNode = &g_stEventNodes[u32EventID - 1];

        // 执行回调链
        CallbackNode_TypeDef* pstCallback = pstEventNode->pstCallbackList;
        while(pstCallback != NULL) {
            // 同时传递固定参数和动态参数
            pstCallback->pfnCallback(pstCallback->pvFixedArgs, pvDynamicArgs);
            pstCallback = pstCallback->pstNext;
        }
    }

    // 返回成功
    return EVENT_OK;
}
